package fun.qu_an.velocity.whitelist.whitelist;

import com.velocitypowered.api.proxy.Player;
import fun.qu_an.lib.basic.util.result.Result;
import fun.qu_an.velocity.whitelist.VelocityWhitelist;
import fun.qu_an.velocity.whitelist.api.whitelist.Whitelist;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;

import static fun.qu_an.velocity.whitelist.api.whitelist.Results.ILLEGAL_PLAYER_NAME;
import static fun.qu_an.velocity.whitelist.util.Utils.PROXY_UTIL;

public class WhitelistManagements {
	private static final @NotNull Whitelist whitelist;

	static {
		whitelist = PROXY_UTIL.isOnlineMode()
			? Whitelist.newConcurrent(
			VelocityWhitelist.DATA_DIRECTORY.resolve("whitelist.json"),
			true)
			: Whitelist.newConcurrent(
			VelocityWhitelist.DATA_DIRECTORY.resolve("whitelist_offline.json"),
			false);
	}

	/**
	 * 加载白名单
	 *
	 * @see Whitelist#load()
	 */
	public static Result load() {
		return whitelist.load();
	}

	/**
	 * 添加白名单
	 *
	 * @return 添加单个玩家时有准确的返回值。<p>
	 * 批量添加时：当有任意添加成功的玩家时，返回添加成功的玩家和UUID列表。如果全部失败则返回失败。
	 * @see Whitelist#add(String)
	 */
	public static Result add(String @NotNull ... playerNames) {
		if (playerNames.length == 0) {
			return ILLEGAL_PLAYER_NAME;
		}

		// 添加单个玩家时有准确的返回值。
		if (playerNames.length == 1) {
			Result result = whitelist.add(playerNames[0]);
			Result saveResult = whitelist.save();
			if (saveResult.isFailed()) {
				return Result.failure().subResult(saveResult);
			}
			return result;
		}

		boolean anySucceed = false;
		// 返回值列表
		List<String> messages = new ArrayList<>(playerNames.length);
		for (String playerName : playerNames) {
			if (playerName.isEmpty()) {
				continue;
			}
			Result result1 = whitelist.add(playerName);
			if (result1.isSucceeded()) {
				anySucceed = true;
				messages.add(result1.message());
			}
		}

		// 批量添加时：当有任意添加成功的玩家时，返回添加成功的玩家和UUID列表。如果全部失败则返回失败。
		if (anySucceed) {
			// 生成返回值
			String message = "[" + String.join(",", messages) + "]";
			Result result = Result.success(message);
			Result saveResult = whitelist.save();
			if (saveResult.isFailed()) {
				// 追加保存失败的结果
				return Result.failure().subResult(saveResult);
			}
			return result;
		}

		return Result.failure();
	}

	/**
	 * 移除白名单
	 *
	 * @return 添加单个玩家时有准确的返回值。<p>
	 * 批量添加时：当有任意删除成功的玩家时，返回成功的玩家列表，否则返回失败
	 * @see Whitelist#remove(String)
	 */
	public static Result remove(String @NotNull ... playerNames) {
		if (playerNames.length == 0) {
			return ILLEGAL_PLAYER_NAME;
		}
		// 删除单个玩家时有准确的返回值。
		if (playerNames.length == 1) {
			Result result = whitelist.remove(playerNames[0]);
			Result saveResult = whitelist.save();
			if (saveResult.isFailed()) {
				// 追加保存失败的结果
				return Result.failure().subResult(saveResult);
			}
			return result;
		}

		boolean anySucceed = false;
		// 返回值列表
		List<String> messages = new ArrayList<>(playerNames.length);
		for (String playerName : playerNames) {
			if (playerName.isEmpty()) {
				continue;
			}
			Result result1 = whitelist.remove(playerName);
			if (result1.isSucceeded()) {
				anySucceed = true;
				messages.add(result1.message());
			}
		}

		// 批量删除时：当有任意删除成功的玩家时，返回成功的玩家列表，否则返回失败
		if (anySucceed) {
			// 生成返回值
			String message = "[" + String.join(",", messages) + "]";
			Result result = Result.success(message);
			Result saveResult = whitelist.save();
			if (saveResult.isFailed()) {
				// 追加保存失败的结果
				return Result.failure().subResult(saveResult);
			}
			return result;
		}

		return Result.failure();
	}

	/**
	 * 获取白名单玩家列表
	 *
	 * @see Whitelist#list()
	 */
	public static List<String> list() {
		return whitelist.list();
	}

	/**
	 * 检查玩家是否在白名单内，并更新白名单中的玩家名
	 *
	 * @see Whitelist#updatePlayer
	 */
	public static boolean checkAndUpdate(@NotNull Player player) {
		Result result = whitelist.updatePlayer(player.getUniqueId(), player.getUsername());
		if (result.isSucceeded()) whitelist.save();
		return !result.isFailed();
	}

	public static boolean test(String player) {
		return whitelist.getUuidByName(player) != null;
	}
}
